#define _CRT_SECURE_NO_DEPRECATE
#include <cstdio>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include "ext_rational.h"

#pragma comment(linker, "/STACK:400000000")

using namespace std;

int ALPH_SIZE;
int ROOT_LENGTH;
ext_rational beta;
double delta;

// ANTIDICTIONARY CONSTRUCTION

vector<string> queue[2];

char *bij;

string lexmin(const string& s, int dir){
  int i, cur = 0, sp = 0, fp = (int)s.length() - 1;
  if (dir < 0){
    swap(sp, fp);
  }
  for (i=0; i<ALPH_SIZE; i++){
    bij[i] = 0;
  }
  string res(s);
  for (i=sp; i != fp; i += dir){
    if (!bij[s[i]-'a']){
      bij[s[i]-'a'] = 'a' + cur;
      cur++;
    }
    res[i] = bij[s[i]-'a'];
  }
  return res;
}

int total;
//short next[MAX][27];
//char terminal[MAX];
vector<vector<int> > next;
vector<bool> terminal;

void init(){
  bij = new char [ALPH_SIZE+1];
  total = 1;
  for (int i=0; i<=total; i++){
    terminal.push_back(false);
    next.push_back(vector<int>(ALPH_SIZE, 0));
  }
}

bool forbidden(const string& z, int dir){
  int cv = 1;
  int i, sp = 0, fp = (int)z.length() - 1;
  string s = lexmin(z, dir);
  if (dir < 0){
    swap(sp, fp);
  }
  for (i=sp; i != fp; i += dir){
    int c = s[i]-'a';
    if (!next[cv][c]) return false;
    cv = next[cv][c];
    if (terminal[cv]) return true;
  }
  return false;
}

void add_word(const string& s){
  int cv = 1;
  unsigned i;
  for (i=0; i<s.size(); i++){
    int c = s[i]-'a';
    if (!next[cv][c]){
      total++;
      next.push_back(vector<int>(ALPH_SIZE, 0));
      terminal.push_back(false);
      next[cv][c] = total;
    }
    cv = next[cv][c];
  }
  terminal[cv] = 1;
}

// AUTOMATON CONSTRUCTION

int ** dfa;
char * last;
char ** sigma;
char ** back;
int * lf;

int * q;
int qbeg, qend;

inline void q_push(int x){
  q[++qend] = x;
}

void make_permut(char* p1, char* p2){
  int i;
  for (i=0; i<ALPH_SIZE; i++){
    if (p1[i] >= 0){
      p1[i] = p2[p1[i]];
    }
  }
}

void cnt_vertex(int v){
  int c;
  char * zsigma = new char [ALPH_SIZE];
  char clast = last[v];
  for (c=0; c<=clast+1; c++){
    if (c >= ALPH_SIZE) return;
    if (!dfa[v][c]){
      char d = sigma[v][c];
      if (d < 0){
        d = last[lf[v]] + 1;
      }
      dfa[v][c] = dfa[lf[v]][d];
      back[v][c] = 1;
    }
    else{
      int u = dfa[v][c];
      if (terminal[u]){
        dfa[v][c] = 0;
        continue;
      }
      q_push(u);
      last[u] = (c > clast) ? c : clast;
      memcpy(sigma[u], sigma[v], sizeof(char) * ALPH_SIZE);
      int d = sigma[v][c];
      if (d < 0){
        d = last[lf[v]] + 1;
        sigma[u][c] = d;
      }
      lf[u] = dfa[lf[v]][d];
      int zv = lf[v];
      while (back[zv][sigma[u][c]]){
        memcpy(zsigma, sigma[zv], sizeof(char) * ALPH_SIZE);
        if (zsigma[sigma[u][c]] < 0){
          zsigma[sigma[u][c]] = last[lf[zv]] + 1;
        }
        make_permut(sigma[u], zsigma);
        zv = lf[zv];
      }
    }
  }
  for (c=clast+2; c<ALPH_SIZE; c++){
    dfa[v][c] = dfa[v][clast+1];
    back[v][c] = back[v][clast+1];
  }
}

void build_dfa(){
  dfa = new int * [total + 1];
  sigma = new char * [total + 1];
  back = new char * [total + 1];
  last = new char [total + 1];
  lf = new int [total + 1];
  int i, j;
  for (i=1; i<=total; i++){
    dfa[i] = new int [ALPH_SIZE];
    sigma[i] = new char [ALPH_SIZE];
    back[i] = new char [ALPH_SIZE];
    last[i] = 0;
    for (j=0; j<ALPH_SIZE; j++){
      dfa[i][j] = next[i][j];
      sigma[i][j] = -1;
      back[i][j] = 0;
    }
    next[i].clear();
  }
  for (i=1; i<ALPH_SIZE; i++){
    dfa[1][i] = 2;
  }
  q = new int [total + 1];
  qbeg = 1; qend = 0;
  q_push(2);
  last[1] = -1;
  lf[1] = lf[2] = 1;
  while (qbeg <= qend){
    cnt_vertex(q[qbeg]);
    qbeg++;
  }
  next.clear();
  terminal.clear();
  delete[] sigma;
  delete[] back;
  delete[] q;
  delete[] last;
  delete[] lf;
}

// ANSWER CALCULATION

double * cnt_new;
double * cnt_old;

double grate;

int scc_num, nontriv_scc_num;
int * scc;
vector<int> cur_scc;

#define USE_ORACLE false

const int MAXITER = 500;
const int MINITER = 50;

void cnt_algo2(){
  int i, j, k;
  char h;
  cnt_old = new double [total+1];
  memset(cnt_old, 0, sizeof(double) * (total + 1));
  cnt_new = new double [total+1];
  memset(cnt_new, 0, sizeof(double) * (total + 1));
  cnt_old[1] = 1;
  double pcomp = 1, ccomp, pprate, prate, crate, lastmin=0, lastmax=0, pz=-1;
  for (i=0; i<MAXITER; i++){
    for (j=1; j<=total; j++){
      for (h=0; h<ALPH_SIZE; h++){
        k = dfa[j][h];
        if (!k) continue;
        cnt_new[k] += cnt_old[j];
      }
      cnt_new[j] += cnt_old[j];
    }
    ccomp = 0;
    for (j=1; j<=total; j++){
      ccomp += cnt_new[j];
      cnt_old[j] = cnt_new[j];
      cnt_new[j] = 0;
    }
    crate = ccomp / pcomp;
    // ORACLE HERE
    if (i > 2){
      if ((prate <= pprate) && (prate <= crate)) lastmin = prate;
      if ((prate >= pprate) && (prate >= crate)) lastmax = prate;
    }
    if ((i >= MINITER) && (lastmin == 0) && (lastmax == 0)){
      double z = crate / prate;
      if (fabs(z - pz) <= 1e-9){
        grate = (crate / (1-z)) - 1;
        printf("\nMonotonous sequence here!\n\n");
        return;
      }
      pz = z;
    }
    if ((i >= MINITER) && (fabs(crate - prate) < delta) && (lastmin > 0) && (lastmax > 0) && (lastmax-lastmin < delta)){
      grate = crate - 1;
      printf("\nOscillating sequence - %d iterations required\n\n", i);
      return;
    }
    pcomp = ccomp;
    if (i) pprate = prate;
    prate = crate;
  }
  printf("\nNot enough iterations! Only %.20lf difference is found\n\n", max(fabs(crate - prate), lastmax-lastmin));
  grate = crate - 1;
}

void cnt_algo1(){
  double minrate, maxrate, crate, alpha;
  int cs = (int)cur_scc.size(), k, i, j, iter = 0;
  while (iter < MAXITER){
    iter++;
    for (i=0; i<cs; i++){
      k = cur_scc[i];
      for (j=0; j<ALPH_SIZE; j++){
        if (dfa[k][j] > 0){
          cnt_new[dfa[k][j]] += cnt_old[k];
        }
      }
      cnt_new[k] += cnt_old[k];
    }
    minrate = 1e100;
    maxrate = 0;
    for (i=0; i<cs; i++){
      k = cur_scc[i];
      crate = cnt_new[k] / cnt_old[k];
      if (crate < minrate) minrate = crate;
      if (crate > maxrate) maxrate = crate;
      cnt_old[k] = cnt_new[k];
      cnt_new[k] = 0;
    }
    //printf("\nITERATION %d: %.20lf\n", ++iter, (maxrate+minrate)/2);
    if (maxrate - minrate < 2 * delta){
      alpha = (minrate + maxrate) / 2 - 1;
      if (alpha > grate) grate = alpha;
      printf("\n%d iterations used\n\n", iter);
      return;
    }
  }
  printf("\nNot enough iterations or precision error! %.20lf precision only!\n\n", (maxrate-minrate)/2);
  grate = (minrate + maxrate) / 2 - 1;
}

int scc_total_pow;

void solve_cur_scc(){
  int i, k, j, edgnum = 0;
  scc_total_pow += (int)cur_scc.size();
  for (i=0; i<(int)cur_scc.size(); i++){
    k = cur_scc[i];
    for (j=0; j<ALPH_SIZE; j++){
      if (scc[k] != scc[dfa[k][j]]){
        dfa[k][j] = 0;
      }
      else{
        edgnum++;
      }
    }
  }
  delete[] scc;
  
  cnt_old = new double [total+1];
  memset(cnt_old, 0, sizeof(double) * (total + 1));
  cnt_new = new double [total+1];
  memset(cnt_new, 0, sizeof(double) * (total + 1));
  for (i=0; i<(int)cur_scc.size(); i++){
    k = cur_scc[i];
    cnt_new[k] = 0;
    cnt_old[k] = 1;
  }
  
  if (edgnum == (int)cur_scc.size()){
    if (grate == 0) grate = 1;
    return;
  }
  nontriv_scc_num++;
  cnt_algo1();
}


// TARJAN ALGORITHM

int * stack;
int * in_time;
int * z_time;
char * instack;
int ssize, curtime;

void dfs(int v){
  int k;
  char i;
  ++curtime;
  in_time[v] = z_time[v] = curtime;
  stack[++ssize] = v;
  instack[v] = 1;
  for (i=0; i<ALPH_SIZE; i++){
    k = dfa[v][i];
    if (!k) continue;
    if (!in_time[k]){
      dfs(k);
      if (z_time[k] < z_time[v]){
        z_time[v] = z_time[k];
      }
    }
    else if (instack[k] && z_time[k] < z_time[v]){
      z_time[v] = z_time[k];
    }
  }
  if (scc_num > 1) return;
  if (z_time[v] == in_time[v]){
    if (stack[ssize] == v){
      scc[v] = 0;
      instack[v] = 0;
      ssize--;
    }
    else{
      scc_num++;
      if (scc_num > 1){
        printf("Achtung! There is more than one scc!\n");
        fflush(stdout);
        return;
      }
      cur_scc.clear();
      do{
        k = stack[ssize--];
        scc[k] = scc_num;
        instack[k] = 0;
        cur_scc.push_back(k);
      }while (k != v);
    }
  }
}

void divide_scc_solve(){
  if (!USE_ORACLE){
    stack = new int [total + 1];
    ssize = 0;
    in_time = new int [total + 1];
    memset(in_time, 0, sizeof(int) * (total + 1));
    curtime = 0;
    z_time = new int [total + 1];
    instack = new char [total + 1];
    memset(instack, 0, sizeof(char) * (total + 1));
    scc = new int [total + 1];
    memset(scc, 0, sizeof(int) * (total + 1));
    dfs(1);
    delete[] stack;
    delete[] in_time;
    delete[] instack;
    delete[] z_time;
    printf("The number of non-singleton strongly connected components: %d\n", scc_num);
    fflush(stdout);
    if (scc_num < 2){
      solve_cur_scc();
    }
    printf("The number of non-trivial scc: %d\n", nontriv_scc_num);
    printf("The number of vertices in scc: %d\n", scc_total_pow);
    printf("\n");
    fflush(stdout);
  }
  else{
    cnt_algo2();
  }
}

// DEBUG OUTPUT

#define OUTPUT_ANTIDICTIONARY false

void dfs_output(int cv, const string& str){
  if (terminal[cv]) printf("%s\n", str.c_str());
  int i;
  for (i=0; i<ALPH_SIZE; i++){
    if (next[cv][i]){
      string ns = str;
      ns += 'a'+i;
      dfs_output(next[cv][i], ns);
    }
  }
}

#define OUTPUT_DFA false

void output_dfa(){
  int i, j;
  printf("\n");
  for (i=1; i<=total; i++){
    if (terminal[i]) continue;
    printf("Vertex number %d: \n", i);
    for (j=0; j<ALPH_SIZE; j++){
      printf("%d ", dfa[i][j]);
    }
    printf("\n\n");
  }
}

void clear_data(){
  queue[0].clear();
  queue[1].clear();
  delete[] bij;
  grate = 0;
  scc_num = 0;
  nontriv_scc_num = 0;
  scc_total_pow = 0;
}

int main(){
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  scanf("%d%d", &ALPH_SIZE, &ROOT_LENGTH);
  scanf("%d%d%d", &beta.num, &beta.denum, &beta.p);
  scanf("%lf", &delta);
  init();
  int prv = 0, nxt, i, j;
  queue[prv].push_back("a");
  do{
    nxt = 1-prv;
    queue[nxt].clear();
    for (i=0; i<(int)queue[prv].size(); i++){
      string w = queue[prv][i];
      
      int len = (int)w.length();
      
      char maxlet='a';
      for (j=0; j<len; j++){
        if (w[j] > maxlet){
          maxlet = w[j];
        }
      }
      
      string u = w;
      int ul = len, cind = 0;
      while (ext_rational(ul, len, 0) < beta){
        u += w[cind];
        ul++;
        cind = (cind + 1) % len;
      }
      
      int ok = 1;
      
      for (j=len; j<ul; j++){
        string v = u.substr(0, j);
        if (forbidden(v, -1)){
          ok = 0;
          break;
        }
      }

      if (forbidden(u, 1)){
        ok = 0;
      }

      if (ok){
        add_word(u);
      }
      
      if (len < ROOT_LENGTH){
        char ch;
        for (ch='a'; ch<=maxlet; ch++){
          string nw = w;
          nw += ch;
          if (!forbidden(nw, -1)){
            queue[nxt].push_back(nw);
          }
        }
        if (maxlet-'a'+1 < ALPH_SIZE){
          w += maxlet+1;
          queue[nxt].push_back(w);
        }
      }
    }
    prv = nxt;
  } while (!queue[prv].empty());
  
  if (OUTPUT_ANTIDICTIONARY){
    dfs_output(1, "");
    fflush(stdout);
  }
  
  int vert_num = 0, words_num = 0;
  for (i=1; i<=total; i++){
    if (terminal[i]) words_num++;
    else vert_num++;
  }
  printf("The number of words = %d\n", words_num);
  printf("The number of vertices = %d\n", vert_num);
  fflush(stdout);
  
  build_dfa();
  if (OUTPUT_DFA){
    output_dfa();
    fflush(stdout);
  }
  printf("\nDFA built!\n\n");

  divide_scc_solve();
  
  printf("%.20lf\n", grate);

  clear_data();

  return 0;
}
